home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v10n05.arc
/
2BOTH.ARC
/
FCOMMON.C
< prev
next >
Wrap
Text File
|
1991-02-13
|
10KB
|
387 lines
/* PROJECT....: 2FILE.C and 2FLOPPY.C
** FILE.......: fcommon.c
** VERSION....: 1.0 (Turbo C++ 1.0 & MSC 5.0)
** AUTHOR.....: Stephen D. Cooper
** NOTICE.....: Copyright 1990 ZIFF Communications Co.
**
** NOTES......: This file contains those routines that are used by
** both 2FILE.C and 2FLOPPY.C.
**
** COMPILE....: Using Turbo C:
** 2file.exe ==> tcc -D_2FILE_C_ -O 2file.c fcommon.c
** 2floppy.exe ==> tcc -mc -O 2floppy.c fcommon.c
**
** Using MSC:
** 2file.exe ==> cl /D_2FILE_C_ 2file.c fcommon.c
** 2floppy.exe ==> cl /AC 2floppy.c fcommon.c
*/
/********************************************************************
** INCLUDE FILES **
********************************************************************/
#define ERROR_FILE
#include <conio.h>
#include <ctype.h>
#include <dos.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "compiler.h"
#include "fcommon.h"
#if defined _2FILE_C_
#include "2fil_err.h"
#else
#include "2flo_err.h"
#endif
/********************************************************************
*********************************************************************
** CODE STARTS **
*********************************************************************
********************************************************************/
/*********************************************************************
** FUNCTION check_filename() **
*********************************************************************/
int check_filename(char *destname, char *given, DISKSTATS *dstats)
{
char drive[MAXDRIVE],
dir[MAXDIR],
name[MAXFILE],
ext[MAXEXT];
/*
** Parse the file name
*/
SPLITPATH(strupr(given), drive, dir, name, ext);
/*
** Check drive letter -- If not given, default is current drive
*/
if(!isalpha(*drive))
{
#if defined(TURBO_C)
drive[0] = getdisk() + 'A';
#else
_dos_getdrive(drive);
drive[0] += 'A' - 1;
#endif
drive[1] = ':';
drive[2] = '\0';
}
if(drive[0] - 'A' == dstats->drivenum)
return(ERR_SAME_DRIVE);
/*
** Check for a file name -- If not given, return an error
** NOTE: This does not check for a valid file name --
** that will be found when we try to open the file
*/
if(*name == '\0')
return(ERR_NO_FILENAME);
/*
** Check for an extension -- If not given, use .FLP as default
*/
if(*ext == '\0')
strcpy(ext, ".FLP");
/*
** Put it all back together again
*/
MAKEPATH(destname, drive, dir, name, ext);
return(ERR_NO_ERRORS);
}
/*********************************************************************
** FUNCTION check_numargs() **
*********************************************************************/
int check_numargs(int argc, int minargs, int maxargs)
{
if(argc < minargs)
return(ERR_TOO_FEW_ARGS);
else if(argc > maxargs)
return(ERR_TOO_MANY_ARGS);
else
return(ERR_NO_ERRORS);
}
/*********************************************************************
** FUNCTION continue_yn() **
*********************************************************************/
int continue_yn(void)
{
cputs("Continue (Y/N)? ");
return(getyn());
}
/********************************************************************
** FUNCTION....: ctrlbrk_handler(void) **
** **
** RETURNS.....: Nothing **
** **
** CALLS.......: getyn() **
** err_exit() **
** **
** NOTES.......: ctrlbrk_handler() is the program's Ctrl-Break **
** handler. If the user presses Ctrl-Break, this **
** routine displays a message asking the user to **
** confirm the program exit. If yes, err_exit() is **
** called with ERR_USER_ABORT, else the program **
** resumes operation. **
********************************************************************/
void ctrlbrk_handler(void)
{
/*
** Turn off the Ctrl-Break handler
** and ignore any further Ctrl-Breaks
*/
signal(SIGINT, SIG_IGN);
/*
** Ask the user to confirm the Ctrl-Break.
** Exit if confirmed, return if not.
*/
printf("\nCtrl-Break was pressed -- "
"Do you wish to exit the program (Y/N)? ");
if(getyn() == 'Y')
{
printf("\n\n");
err_exit(ERR_USER_ABORT);
}
printf("\n\n");
signal(SIGINT, ctrlbrk_handler);
}
/********************************************************************
** FUNCTION....: err_exit(int errcode) **
** **
** PARAMETERS..: int errcode - Error code that points to the **
** message to display to the user **
** **
** RETURNS.....: Nothing **
** **
** NOTES.......: err_exit() displays an error message, cleans-up **
** if needed, and exits to DOS with an ERRORLEVEL **
********************************************************************/
void err_exit(int errcode)
{
if(errcode != ERR_USER_ABORT)
printf("ERROR(%d): ", errcode);
printf("%s.\n\n", errmsg[errcode]);
if(prg_status == HARDERR_CRITICAL)
{
free(read_buff);
fcloseall();
#if defined(_2FILE_C_)
remove(filename);
#endif
}
exit(errcode);
}
/*********************************************************************
** FUNCTION floppyletter_2_number() **
*********************************************************************/
int floppyletter_2_number(unsigned *drivenum, char *drive)
{
*drive = toupper(*drive);
if(*drive == 'A' || *drive == 'B')
if(*(drive + 1) == ':' && *(drive + 2) == '\0')
{
*drivenum = *drive - 'A';
return(ERR_NO_ERRORS);
}
return(ERR_FLOPPY_LETTER);
}
/********************************************************************
** FUNCTION....: getyn(void) **
** **
** RETURNS.....: 'Y' = user pressed 'Y' **
** 'N' = user pressed 'N' **
** **
** NOTES.......: getyn() waits for the user to press either 'Y' **
** or 'N' (either upper or lower case). **
** NOTE: The user keypress is echoed. **
********************************************************************/
int getyn(void)
{
int retval = 'A';
while(retval != 'Y' && retval != 'N')
retval = toupper(getche());
return(retval);
}
/********************************************************************
** FUNCTION....: harderr_handler() **
** **
** RETURNS.....: **
** **
** NOTES.......: I know that this function is VERY hard to read, **
** but it must be this way in order for it to work **
** with both Turbo C and MSC. To get the **
** definition of the UPPER CASE words, please look **
** at fcommon.h. **
********************************************************************/
#pragma argsused
HARDERR_HANDLER
{
char buff[2];
if(prg_status == HARDERR_NON_CRITICAL)
{
if((ax & 0x8000) == 0) /* bit 15 -> 0 = disk */
{
buff[0] = (ax & 0x00FF) + 'A'; /* disk drive letter */
buff[1] = '\0';
cputs("A disk error has occurred. Please make sure ");
cputs("that there\r\n");
cputs("is a disk in drive ");
cputs(buff);
cputs(": and that the drive door is closed.\r\n\n");
if(continue_yn() == 'N')
harderr_status = HARDERR_ABORT;
else
harderr_status = HARDERR_RETRY;
}
else
{
cputs("A non-disk critical hardware error has ");
cputs("occurred.\r\n");
cputs("Please make sure you're computer is working ");
cputs("properly and try again.\r\n\n");
harderr_status = HARDERR_ABORT;
}
}
else
{
cputs("\r\n\nAn unrecoverable hardware error has ");
cputs("occurred. Please try again making sure\r\n");
cputs("that the source drive contains the source disk, ");
cputs("that the destination drive\r\n");
cputs("contains a formatted disk, and that all drive ");
cputs("doors are closed.");
harderr_status = HARDERR_ABORT;
}
cputs("\r\n\n");
HARDRETN(HARDERR_RET_CODE);
#if defined(TURBO_C)
return(HARDERR_IGNORE);
#endif
}
/********************************************************************
** FUNCTION..: read_sectors() **
********************************************************************/
int read_sectors(int track, int head, char *buff, DISKSTATS *dstats)
{
int retval;
unsigned char *newbuff;
union REGS inregs, outregs;
/*
** Set up registers for call
*/
inregs.h.ah = BIOSFUNC_READ_SECTOR;
if(dstats->numsectors > 9)
inregs.h.al = 9;
else
inregs.h.al = dstats->numsectors;
inregs.h.ch = track;
inregs.h.cl = 1;
inregs.h.dh = head;
inregs.h.dl = dstats->drivenum;
inregs.x.bx = FP_OFF((char far *)buff);
retval = sector_read(&inregs, &outregs, buff, dstats);
if(retval != 0)
return(retval);
if(dstats->numsectors > 9)
{
inregs.h.al = dstats->numsectors - 9;
inregs.h.cl = 10;
newbuff = buff + (9 * dstats->sectorsize);
inregs.x.bx = FP_OFF((char far *)newbuff);
retval = sector_read(&inregs, &outregs, newbuff, dstats);
}
return(retval);
}
/********************************************************************
** FUNCTION..: reset_drive() **
********************************************************************/
int reset_drive(int drivenumber)
{
union REGS regs;
regs.h.ah = BIOSFUNC_RESET;
regs.h.dl = drivenumber;
int86(BIOS_DISK, ®s, ®s);
return(regs.h.ah == 0 ? 0 : ERR_RESETTING_DRIVE);
}
/********************************************************************
** FUNCTION..: sector_read() **
********************************************************************/
int sector_read(union REGS *inregs, union REGS *outregs, char *buff,
DISKSTATS *dstats)
{
int try_cntr = 3;
struct SREGS sregs;
/*
** Try 3 times if not succesful
*/
do
{
sregs.es = FP_SEG((char far *)buff);
int86x(BIOS_DISK, inregs, outregs, &sregs);
if(outregs->h.ah != 0)
reset_drive(dstats->drivenum);
} while(outregs->h.ah != 0 && --try_cntr > 0);
return(outregs->h.ah == 0 ? 0 : ERR_READING_FLOPPY);
}
/******************************
*******************************
**** END OF FILE fcommon.c ****
*******************************
******************************/